//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace Microsoft.Research.DataLayer
{
    using System;
    using System.Collections.Generic;

    /// <summary>
    /// 
    /// </summary>
    [Serializable]
    internal class FilterAfterCalls : IDataLayerSecurityAfterCalls
    {
        /// <summary>
        /// 
        /// </summary>
        private List<IDataLayerSecurityFilter> filters;

        /// <summary>
        /// Initializes a new instance of the <see cref="FilterAfterCalls"/> class.
        /// </summary>
        /// <param name="filters">The filters.</param>
        public FilterAfterCalls(List<IDataLayerSecurityFilter> filters)
        {
            this.filters = filters;
        }

        #region IDataLayerSecurityAfterCalls Members

        public SecurityAction Object(out Exception error, ref Connection.Storage storage, ref Connection.Action action,
            ref List<Parameter> paramListReq, ref List<Parameter> paramListResp)
        {
            error = null;

            // No filters? By default block all traffic
            if (filters == null)
                return SecurityAction.Deny;

            foreach (IDataLayerSecurityFilter filter in filters)
            {
                if (filter.After.Object(out error, ref storage, ref action, ref paramListReq, ref paramListResp) == SecurityAction.Deny)
                    return SecurityAction.Deny;
            }

            return SecurityAction.Allow;
        }

        public SecurityAction Object(out Exception error, ref Connection.Storage storage, ref Connection.Action action,
            Connection.ObjectCreator creator, ref List<IObject> results)
        {
            error = null;

            // No filters? By default block all traffic
            if (filters == null)
                return SecurityAction.Deny;

            foreach (IDataLayerSecurityFilter filter in filters)
            {
                if (filter.After.Object(out error, ref storage, ref action, creator, ref results) == SecurityAction.Deny)
                    return SecurityAction.Deny;
            }

            return SecurityAction.Allow;
        }

        public SecurityAction Relation(out Exception error, ref Connection.Action action, ref IObject obj1, ref IObject obj2)
        {
            error = null;

            // No filters? By default block all traffic
            if (filters == null)
                return SecurityAction.Deny;

            foreach (IDataLayerSecurityFilter filter in filters)
            {
                if (filter.After.Relation(out error, ref action, ref obj1, ref obj2) == SecurityAction.Deny)
                    return SecurityAction.Deny;
            }

            return SecurityAction.Allow;
        }

        public SecurityAction Relation(out Exception error, ref Connection.Action action,
            ref IObject obj1, ref Connection.Storage obj2Type, Connection.ObjectCreator creator, ref List<IObject> results)
        {
            error = null;

            // No filters? By default block all traffic
            if (filters == null)
                return SecurityAction.Deny;

            foreach (IDataLayerSecurityFilter filter in filters)
            {
                if (filter.After.Relation(out error, ref action, ref obj1, ref obj2Type, creator, ref results) == SecurityAction.Deny)
                    return SecurityAction.Deny;
            }

            return SecurityAction.Allow;
        }

        public SecurityAction Relation(out Exception error, ref Connection.Action action, ref IObject obj1,
            ref string field, ref Connection.Storage obj2Type, Connection.ObjectCreator creator, ref List<IObject> results)
        {
            error = null;

            // No filters? By default block all traffic
            if (filters == null)
                return SecurityAction.Deny;

            foreach (IDataLayerSecurityFilter filter in filters)
            {
                if (filter.After.Relation(out error, ref action, ref obj1, ref field, ref obj2Type, creator, ref results) == SecurityAction.Deny)
                    return SecurityAction.Deny;
            }

            return SecurityAction.Allow;
        }

        public SecurityAction Relation(out Exception error, ref Connection.Action action, ref IObject obj1,
            ref Connection.Storage obj2, ref string revKey, ref List<Parameter> paramListReq, ref List<Parameter> paramListResp)
        {
            error = null;

            // No filters? By default block all traffic
            if (filters == null)
                return SecurityAction.Deny;

            foreach (IDataLayerSecurityFilter filter in filters)
            {
                if (filter.After.Relation(out error, ref action, ref obj1, ref obj2, ref revKey, ref paramListReq, ref paramListResp) == SecurityAction.Deny)
                    return SecurityAction.Deny;
            }

            return SecurityAction.Allow;
        }

        #endregion
    }
}
